home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
001-025
/
scopedisk24
/
qrt14src
/
pattern.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-18
|
5KB
|
230 lines
/**********************************************************
Pattern and texture module
**********************************************************/
#include "qrt.h"
#include "pattern.h"
/* #define PATTERNDEBUG 1 */
/**********************************************************
Given two coordinates on the surface of an object,
and a pointer to a colorinfo structure, this routine
fills the structure with the objects color info at
this location. If the object does not have an associated
pattern, its default colorinfo is returned. The
routine returns TRUE if the pattern is hit, FALSE
otherwise.
**********************************************************/
int Find_Color(obj, pattern, loc, cinfo, xmult, ymult)
OBJ_PTR obj;
PATTERN_PTR pattern;
VECT_PTR loc;
CINFO_PTR cinfo;
float xmult, ymult;
{
PATTERN_PTR patt;
float modpos1, modpos2, pos1, pos2;
int modx, mody;
if (pattern==NULL) { /* no pattern */
copy_colorinfo(cinfo,&(obj->cinfo));
return(FALSE);
}
# ifdef ROBUST
if (pattern->type != PATT_HEADER)
Error(INTERNAL_ERROR,1001);
if ((xmult==0) || (ymult==0))
Error(ZERO_MULTIPLIER,1002);
# endif
/* find object relative position */
(*(ObjData[obj->type].RelPos))(obj,loc,&pos1,&pos2);
pos1 /= xmult; /* x and y multipliers */
pos2 /= ymult; /* for pattern sizing */
modx = (int)(pos1 / (pattern->xsize));
if (pos1<0) modx--;
mody = (int)(pos2 / (pattern->ysize));
if (pos2<0) mody--;
modpos1 = pos1 - ((float)modx * pattern->xsize);
modpos2 = pos2 - ((float)mody * pattern->ysize);
# ifdef PATTERNDEBUG
printf("FINDCOLOR: modpos1,2 = %f %f\n",modpos1, modpos2);
printf(" mod x,y = %d %d\n",modx, mody);
printf(" mult1,2 = %f %f\n",xmult,ymult);
# endif
patt = pattern->child;
while (patt!=NULL) {
THEWORLD.pattern_matches++;
if ((*(PattData[patt->type].PattHit))(modpos1, modpos2, patt)) {
copy_colorinfo(cinfo,&(patt->cinfo));
return(TRUE);
}
patt = patt->sibling;
}
copy_colorinfo(cinfo,&(obj->cinfo));
return(FALSE);
}
/**********************************************************
Determines if point is inside rectangle
**********************************************************/
int Rect_Hit(pos1, pos2, patt)
float pos1, pos2;
PATTERN_PTR patt;
{
# ifdef PATTERNDEBUG
printf("RECT_HIT: sx,y = %f %f\n",patt->startx,patt->starty);
printf(" ex,y = %f %f\n",patt->endx,patt->endy);
# endif
# ifdef ROBUST
if (patt->type != RECT_PATTERN)
Error(INTERNAL_ERROR,1003);
# endif
if ( (pos1 > patt->startx) &&
(pos1 < patt->endx) &&
(pos2 > patt->starty) &&
(pos2 < patt->endy) ) return(TRUE);
return(FALSE);
}
/**********************************************************
Determines if point is inside circle
**********************************************************/
int Circle_Hit(pos1, pos2, patt)
float pos1, pos2;
PATTERN_PTR patt;
{
float rad, a, b;
# ifdef ROBUST
if (patt->type != CIRCLE_PATTERN)
Error(INTERNAL_ERROR,1004);
# endif
a = (pos1 - patt->radius); /* bug in damn compiler */
b = (pos2 - patt->radius); /* we have to break up */
/* long float operations */
rad = sqr(a)+sqr(b);
# ifdef PATTERNDEBUG
printf("CIRC_HIT\n");
printf(" p1, p2 = %f %f\n",pos1,pos2);
printf(" rad = %f\n",patt->radius);
printf(" crad = %f\n",rad);
# endif
if (rad <= sqr(patt->radius)) return(TRUE);
return(FALSE);
}
/**********************************************************
Determines if point px, py intersects line x1,y1,x2,y2.
Returns true if it does.
**********************************************************/
int line_intersect(px, py, x1, y1, x2, y2)
float px, py, x1, y1, x2, y2;
{
float t;
x1 -= px; x2 -= px; /* translate line */
y1 -= py; y2 -= py;
if ((y1 > 0) && (y2 > 0)) return(FALSE);
if ((y1 < 0) && (y2 < 0)) return(FALSE);
if ((x1 < 0) && (x2 < 0)) return(FALSE);
if (y1 == y2) {
if (y1 != 0) return(FALSE);
if ((x1 > 0) || (x2 > 0)) return(FALSE);
return(TRUE);
}
t = (-y1) / (y2 - y1);
if ((x1 + t * (x2 - x1)) > 0) return(TRUE);
return(FALSE);
}
/**********************************************************
Determines if point is inside Polygon
**********************************************************/
int Poly_Hit(pos1, pos2, patt)
float pos1, pos2;
PATTERN_PTR patt;
{
float xpos, ypos, nxpos, nypos;
PATTERN_PTR lseg;
int count;
# ifdef ROBUST
if (patt->type != POLY_PATTERN)
Error(INTERNAL_ERROR,1005);
# endif
lseg = patt->link;
if (lseg == NULL) Error(INTERNAL_ERROR,1006);
count = 0;
while (lseg->link != NULL) {
if (line_intersect( pos1, pos2,
lseg->startx, lseg->starty,
lseg->link->startx,
lseg->link->starty) )
count++;
lseg = lseg->link;
}
if ((count % 2) == 0) return(FALSE);
return(TRUE);
}